﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.IO;
using System.Reflection;

using IBatisNet.DataMapper;
using IBatisNet.DataMapper.Configuration;

namespace Pg.BioMedics.SDR.Data.Strategy
{
    /// <summary>
    /// Provides data mapper initilization and managment logic. This startegy 
    /// applies custom configuration to data mapper exectly as <see cref="CustomDataMapperStrategy"/>CustomDataMapperStrategy</see>
    /// does it. Moreover this strategy manages in thread data mapper sharing
    /// </summary>
    internal class SharedDataMapperStrategy : IDataMapperStrategy
    {
        #region Static fields

        [ThreadStatic]
        private static ISqlMapper _dataMapper;

        #endregion

        #region Constructors

        /// <summary>
        /// Creates an instance of SharedDataMapperStrategy. This constructor
        /// initialized data mapper share in current thread.
        /// </summary>
        /// <param name="properties"></param>
        internal SharedDataMapperStrategy(NameValueCollection properties)
        {
            try
            {
                if (SharedDataMapperStrategy.SharedDataMapper == null)
                {
                    Stream stream = Assembly.GetExecutingAssembly()
                                            .GetManifestResourceStream("Pg.BioMedics.SDR.Data.SqlMap.config");

                    DomSqlMapBuilder builder = new DomSqlMapBuilder();
                    builder.Properties = properties;

                    SharedDataMapperStrategy.SharedDataMapper = builder.Configure(stream);
                }
            }
            catch (Exception ex)
            {
                throw new SDRDataException("Can't initialize data mapper in shared strategy", ex);
            }
        }

        #endregion

        #region Static properties

        /// <summary>
        /// Gets / sets data mapper stored in thread slot and shared between all
        /// shared data mapper strategies in this thread
        /// </summary>
        private static ISqlMapper SharedDataMapper
        {
            get
            {
                return _dataMapper;
            }

            set
            {
                _dataMapper = value;
            }
        }

        #endregion

        #region IDataMapperStrategy Members

        /// <summary>
        /// Gets instance of initialized data mapper instance
        /// </summary>
        public ISqlMapper DataMapper
        {
            get
            {
                return SharedDataMapperStrategy.SharedDataMapper;
            }
        }

        #endregion
    }
}
